#!/bin/bash
#THIS DRIVER WRITTEN BY MATTHEW VONA ARB FOR THE API 200 E
#WRITTEN USING SN#2631 Revision k.1
#Library Revision 5.9, iChip Rev IL702P16 2.4
#AR-B1320, AMX86 V03.05
#UPDATE: 7/28/2009; Added data file lock handler; Corrected 
#IZS variable handeling in awk diag() routine.  
#-------------------------------------------------------------
#!/usr/bin/env bash
#DIR returns operating directory of the testd script
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# THIS IS THE FUNCTION CALLED IN THE EVENT THAT CTRL+C IS PRESSED
cleanup()
{
	echo "Caught Signal ... cleaning up."
	if !(rm -f Data/.locked > /dev/null); then
        	{
                	exit 1
                 } 
        fi

	echo "Done cleanup ... quitting."
	exit 1
}
#THE DIAGNOSTIC DATA (DIAG) ROUTINE TAKES THE DATA STREAM FROM THE API 400E
#AND TESTS FOR THE RECOGNITION OF KEY WORDS IN EACH LINE OF OUTPUT.
#IF THE KEY WORD IS DETECTED ON THAT LINE, A TEST IS PERFORMED. 
#IF THE TEST SUGGESTS THAT AN ERROR CONDITION EXISTS BASED UPON THE ALLOWABLE
#RANGES SPECIFIED BY THE ARB CHECKSHEET, THE OFFENDING LINE IS WRITTEN OUT 
#TO A FILE IN THE Data DIRECTORY. THE NAME OF THE DESTINATION FILE IS
#errors{HH}. THE FILES CAN THEN BE PARSED AND UTILIZED BY ANY ALERT PROGRAM?DAEMON.
diag()
{
this_name=$(cat ${DIR}/.usr$instance | grep -o "\-r [A-Za-z0-9]*" | awk '{ print $2 }')
thishour=`date "+%H"`
thisalert="errors$thishour"
while read DIAGS
do
awk -v low_flow=${low_flow} -v upp_flow=${upp_flow} -v name=$this_name '
{                                           
# CHECK FOR ANY WARNINGS
if (/WARN/) 
	{ print name " WARNING DETECTED:"$0 }
# TEST THE OZONE FLOW RATE - should be 80 +-15
if ($5 ~ /FL=/ ) 
	{
 	if ((substr($5,4) + 0) <=64)
 	  		{ print name " Ozone Flow is less than 65:"$0 }
	if ((substr($5,4) + 0) >=96)
 	  		{ print name " Ozone Flow is greater than 95:"$0 }
	}
# TEST THE TIME AGAINST DATA LOGGER
if ($4 ~ /TIME=/)
{
#do not run this test during the first or last three minutes of any hour
#this test will run once every hour
	if (substr($4,9,2) == 03)
		{
		#test for off an hour or more
			if (substr($4,6,2) != substr($1,length($1)-8,2))
		  			{ print name " Time off by more than an hour!"}
		#test for off more than 3 minutes. Must add one minute to the 
		#current minute value since the buffer contains values from the previous minute
		   if (sqrt(((substr($4,9,2)+1) - substr($1,length($1)-5,2))^2) > 3 )
		  			{ print name " Time off by more than 2 minutes"}	
		}
}
# TEST THE RANGE
if ($4 ~ /RANGE=/ ) 
	{
 	if (substr($4,7) !~ 200.0)
  		{ print name $4 " not 200:" $0}
	}
# TEST THE SAMPLE FLOW RATE  1000 +-100 for T200U
if ($5 ~ /FLW=/ ) 
	{
 	if (substr($5,5) ~ /XXXX/)
  		{ print name " Sample flow problem:"$0 }
  	else if (substr($5,5) + 0 >= upp_flow + 0)
  	   { print "Sample flow is greater than " upp_flow" "$0}
  	else if (substr($5,5) + 0 <= low_flow + 0)
  	   { print name "Sample flow is less than " low_flow" "$0}
	}
#TEST THE NOX OFFSET
if (/NOX OFFS=/)
	{
	if ((substr ($5,6) + 0) >= 50)
		{ print name " NOx Offset Over Limits: "$0 }
	if ((substr ($5,6) + 0) <= -50)
		{ print name " NOx Offset Under Outside Limits: "$0 }	
	}

#TEST THE NO OFFSET
if (/NO OFFS=/)
	{
	if ((substr ($5,6) + 0) >= 50)
		{ print name " NOx Offset Over Limits: "$0 }
	if ((substr ($5,6) + 0) <= -50)
		{ print name " NOx Offset Under Outside Limits: "$0 }	
	}	
#TEST THE NOX SLOPE
if (/NOX SLOPE=/)

	{
		if ((substr ($5,7) + 0) >= 1.3)
			{ print name " NOX SLOPE GREATER THAN 1.3:" $0}
		if ((substr ($5,7) + 0) <= .7)
			{ print name " NOX SLOPE LESS THAN .7:" $0 }
	}

#TEST THE NO SLOPE
if (/NO SLOPE=/)

	{
		if ((substr ($5,7) + 0) >= 1.3)
			{ print name " NO SLOPE GREATER THAN 1.3:" $0}
		if ((substr ($5,7) + 0) <= .7)
			{ print name " NO SLOPE LESS THAN .7:" $0 }
	}	

#CHECK PMT VOLTAGE
if (/PMT=/)

		{
		if ((substr ($4,5) + 0) >= 5000)
				{ print name " The PMT voltage is high:" $0}
		if ((substr ($4,5) + 0) <= -10 )
				{ print name " The PMT voltage is low:" $0}		
		}
#CHECK NORM PMT VOLTAGE
if (/NORM PMT=/)
		{
		if ((substr ($5,5) + 0) >= 5000)
				{ print name " The NORM PMT voltage is high: " $0}
		if ((substr ($5,5) + 0) <= -10 )
				{ print name " The NORM PMT voltage is low: " $0}
		}			
#CHECK RCELL TEMP
if (/RCELL TEMP=/)
		{
		if ((substr ($5,6) + 0) >= 42)
				{ print name " The RCELL temperature is high: " $0}
		if ((substr ($5,6) + 0) <= 38)
				{ print name " The RCELL temperature is low: " $0}
		}			
#CHECK PMT TEMP
if (/PMT TEMP=/)
		{
		if ((substr ($5,6) + 0) >= 7)
				{ print name " The PMT temperature is high: " $0}
		if ((substr ($5,6) + 0) <= 3)
				{ print name " The PMT temperature is low: " $0}
		}			
#CHECK HVPS 
if (/ HVPS=/)
		{
		if ((substr ($4,6) + 0) >= 901)
				{ print name " The HVPS is high: " $0}
		if ((substr ($4,6) + 0) <= 400)
				{ print name " The HVPS is low: " $0}
		}			

#CHECK PREREACT
if (/ PREREACT=/)
		{
		if ((substr ($4,10) + 0) >= 151)
				{ print name " The Pre-React is too high: " $0}
		if ((substr ($4,10) + 0) <= -21)
				{ print name " The Pre-React is too low: " $0}
		}			

#CHECK MF TEMP 
if (/ MF TEMP=/)
		{
		if ((substr ($5,6) + 0) >=  42)
				{ print name " The MF Temp is too high: " $0}
		if ((substr ($5,6) + 0) <=  38)
				{ print name " The MF Temp is too low: " $0}
		}			

#CHECK RCell pressure 
if (/ RCEL=/)
		{
		if ((substr ($4,6) + 0) >= 4)
				{ print name " The Rcell pressure is too high: " $0}
		}			

}' >> "Data/$thisalert"
done
}
#BEGIN WRITE
#THIS FUNCTION HANDELS READ RIGHT HANDSHAKES BETWEEN VARIOUS DRIVERS
#IN GENERAL, THE DATA IS PLACED IN THE VARIABLE $TIMESTAMP PRIOR TO CALL
#NEXT, IT OPENS THE DATA DIRECTORY AND LOOKS FOR THE .locked FILE
#IF IT EXISTS, IT HANGS OUT UNTIL IT DOESN'T EXIST. AT THAT POINT
#IT CREATES A .locked FILE, AND APPENDS TO THE DATA RECORD.
#FINALLY IT REMOVES THE .locked FILE IT HAS CREATED.
#written by MJV
write()
{
#CONFIRM THAT THERE IS NO HIDDEN FILE CALLED '.locked'
	while [ -e "Data/.locked" ];
		do
			sleep .2;
		done	
	echo "LOCKED" > "Data/.locked";
	#PARSE THE .disabled File
        channel_status=`cat ${DIR}/.disabled$instance`
        #IF THE FILE DOSEN'T EXIT OR IS NOT ACCESIBLE
        #MAKES SURE A VALUE OF 0 IS USED
        if [ `expr $channel_status + 0` -eq 1 ]; then
        	if !(echo "$data" | sed 's/^/'$timestamp'/g'| sed 's/$/'\-\-DISABLED\-\-'/g'| tee -a "Data/$datafile" | diag); then
        	{
        		echo "GENERAL FAILURE WRITING TO RECORD: $#";
        		cleanup;
       	 	}
        	fi
        else
		if !(echo "$data" | sed 's/^/'$timestamp'/g'| tee -a "Data/$datafile" | diag); then
		{
			echo "GENERAL FAILURE WRITING TO RECORD: $#";
			cleanup;
		}
		fi
	fi
	if !(rm -f "Data/.locked" > /dev/null); then
		{
			echo "GENERAL FAILURE REMOVING LOCK: $#";
			exit 1;	
		}
	fi
	if !(timestamp="" && data=""); then
		{
		echo "GENERAL FAILURE CLEARING WRITE BUFFER: $#";
		exit 1;
		}
	fi	
}

#THIS IS THE ACTUAL COMMUNICATION WITH THE INSTRUMENT
#THE TIMER CONTROL. AT THE BEGINING IT TESTS FOR THE 
#EXISTENCE IF TOGGLE VARRIABLES WHICH ARE UTILIZED BOTH BY
#THE COMM ROUTINE runit() AND THE DIAGNOSTICS DATA ROUTINE
#diag()
runit()
{
#IF THE -d, -C, or -p variable is set to on, then append those parameters
#to the sjinn communication string. 
if [ "$dtr_val" = "on" ]; then
 	dtr="--dtr" 
fi
if [ "$ctr_val" = "on" ]; then
 	ctr="--rts"
fi
if [ "$p8n1_val" = "on" ]; then
 	p8n1="-p8n1"
fi
today=`date "+%Y-%d-%m"`
timestamp=$rprt_nm::`date "+%m-%d-%Y_%H:%M"`:::
#THIS IS THE NAME OF THE DATA FILE RIGHT NOW
datafile="$saroad-$today"
#TALK TO THE INSTRUMENT, PRE-APPEND THE TIMESTAMP AND REPORTING NAME TO EACH
#LINE OF OUTPUT AND tee TO THE DATA FILE, then pass to the diag routine.
data=`timeout 20 sjinn -b$bd_rt -d $dvc_prt -s "$cmnd1" -r$rsp_lngth -w$wt_rsp1 $p8n1 $dtr $ctr\
 | grep -v "^$" | sed 's/NOXCNC1=/TNOx=/g' | sed 's/NOCNC1=/TNO=/g' | sed 's/NO2CNC1=/TNO2=/g'` 
write
}
#THIS IS THE FUNCTION RUN IN THE EVENT THAT THE REQUIRED PARAMETERS
#ARE NOT ENTERED.
usage()
{
clear
cat << EOF
usage: $0 options
OPTIONS:
-h	display help
-r	rprt_nm [rn]
-d	dvc_prt [eg, /dev/ttyS0, /dev/ttyUSB1] 
-b	bd_rt [2400,4800,9600,etc.]
-c	cmnd1 
-w	wt_rsp1 [seconds]
-l	rsp_lngth [characters]
-s	SAROAD number of the station
-t	[on/off] (OPTIONAL)
-C	[on/off] (OPTIONAL)
-p	[on/off] (OPTIONAL)
-U	Uppler flow limit alert (OPTIONAL)
-L	Lower flow limit alert (OPTIONAL)
Last updated 9/10/2009
EOF
}
#HELP FUNCTION GIVES BACKGROUND ON THIS DRIVER
help_me ()
{
clear
cat .help
exit 0
}
def_opts ()
{
clear
cat .options
}

##CLEAR ALL VARIABLES               
rprt_nm= ; dvc_prt= ; bd_rt= ; cmnd1= ; wt_rsp1= ; bd_rt= ; rsp_lngth= ; izs_val= ;
dvc_prt= ; frqncy= ; dtr= ; ctr= ; p8n1= ; saroad= ; p8n1= ; id_nmbr= ; 
upp_flow=550 ; low_flow=450 ; instance=1 
##INITIALIZE THE BUFFER
return='NOT WRITTEN TO'
##loop through all variables and parameters
##Note that the position of the colon indicates the presence
##of a parameter to collect. The h parameter simply
##returns the help message.

while getopts 'hr:s:d:b:c:w:l:f:t:C:p:U:L:I:' OPTION
do
	case $OPTION in
		U)
		upp_flow=$OPTARG
		;;
		L)
		low_flow=$OPTARG
		;;
		s)
		saroad=$OPTARG
		;;
		r)
		rprt_nm=$OPTARG
		;;
		d)
		dvc_prt=$OPTARG
		;;
		b)
		bd_rt=$OPTARG
		;;
		c)
		cmnd1=$OPTARG
		;;
		w)
		wt_rsp1=$OPTARG
		;;
		l)
		rsp_lngth=$OPTARG
		;;
		t)
		dtr_val=$OPTARG
		;;
		C)
		ctr_val=$OPTARG
		;;
		p)
		p8n1_val=$OPTARG
		;;
		I)
		instance=$OPTARG
		;;
		h)
		help_me
		exit 1
		;;
		*)
		usage
		exit 1
		;;
	esac
done
#CHECK FOR THE CRITICAL PARAMETERS, IF THEY ARE NOT PRESENT THEN
#RUN THE USAGE FUNCTION WHICH RETURNS THE INSTRUCTIONS FOR PROPER USAGE
#MUST HAVE r d b c w l s
#if [ -z "$rprt_nm" ] || [ -z "$dvc_prt" ] || [ -z "$bd_rt" ] || [ -z "$cmnd1" ] ||
#[ -z "$wt_rsp1" ] || [ -z "$rsp_lngth" ] || [ -z "$saroad" ] 
#	then
#		{
#		usage
#		exit
#		}
#fi
	#INITIALIZED THE RAN VARIABLE. THIS IS USED TO TOGGLE THE TIMER GATE
ran=0
	#TRAP CTRL+C
trap cleanup 1 2 3 6 15
	#SETUP THE OPERATING LOOP
while :
do
	#SET THE SECOND VARIABLE AS THE SECOND VALUE FROM THE DATA STAMP 
second=`date "+%S"`
	#IF THE SECOND VALUE IS LESS THAN 02, BEGIN RUNNING
if [ "$second" -eq "00" ] && [ "$ran" -eq "0" ]; then
	{
		#RUN THE RUNIT FUNCTION
			runit
		#TOGGLE THE RAN VARIABLE SO THAT THE PROCESS WILL NOT REPEAT
		#UNTIL THE BEGINNING OF TH-b9600 -d "/dev/ttyS0" -c "T LIST ALL\\r" -r "API200EU" -w4 -l 1500 -p8n1 -s34305 -i offE NEXT MINUTE.
			ran=1
		#WAIT FOR COMPLETION OF THE RUNIT FUNCTION AND THE VARIABLE
		#SET
			sleep 1
	}
	#IF THE SECOND VALUE IS GREATER THAT 02, RESET RAN TO 0
	#AND WAIT ONE SECOND BEFORE CHECKING AGAIN
else 
	{
		#WAIT ONE SECOND
			sleep .5
		#SET RAN TO 0
			ran=0
	}
fi
done;
exit;

